<div class="content-section introduction">
    <div>
        <span class="feature-title">GMap</span>
        <span>GMap component provides integration with Google Maps API. This sample demontrates
        various uses cases like binding, overlays and events. Click the map to add a new item.</span>
    </div>
</div>

<div class="content-section implementation">
    <p-growl [value]="msgs"></p-growl>
    
    <p-gmap #gmap [style]="&#123;'width':'100%','height':'320px'&#125;" [options]="options" [overlays]="overlays" 
        (onMapClick)="handleMapClick($event)" (onOverlayClick)="handleOverlayClick($event)" (onOverlayDragEnd)="handleDragEnd($event)"></p-gmap>
    <button type="button" pButton label="Clear" icon="fa-close" (click)="clear()" style="margin-top:10px"></button>
    <button type="button" pButton label="Zoom In" icon="fa-search-plus" (click)="zoomIn(gmap.getMap())" style="margin-top:10px"></button>
    <button type="button" pButton label="Zoom Out" icon="fa-search-minus" (click)="zoomOut(gmap.getMap())" style="margin-top:10px"></button>

    <p-dialog showEffect="fade" [(visible)]="dialogVisible" header="New Location" [width]="300">
        <div class="ui-g ui-fluid" *ngIf="selectedPosition">
            <div class="ui-g-2"><label for="title">Label</label></div>
            <div class="ui-g-10"><input type="text" pInputText id="title" [(ngModel)]="markerTitle"></div>
            
            <div class="ui-g-2"><label for="lat">Lat</label></div>
            <div class="ui-g-10"><input id="lat" type="text" readonly pInputText [ngModel]="selectedPosition.lat()"></div>
            
            <div class="ui-g-2"><label for="lng">Lng</label></div>
            <div class="ui-g-10"><input id="lng" type="text" readonly pInputText [ngModel]="selectedPosition.lng()"></div>
            
            <div class="ui-g-2"><label for="drg">Drag</label></div>
            <div class="ui-g-10"><p-checkbox [(ngModel)]="draggable" binary="true" [style]="{'margin-top':'.25em'}"></p-checkbox></div>
        </div>
        <p-footer>
            <div class="ui-dialog-buttonpane ui-helper-clearfix">
                <button type="button" pButton label="Add Marker" icon="fa-plus" (click)="addMarker()"></button>
            </div>
        </p-footer>
    </p-dialog>
</div>

<div class="content-section documentation">
    <p-tabView effect="fade">
        <p-tabPanel header="Documentation">
            <h3>Import</h3>
<pre>
<code class="language-typescript" pCode ngNonBindable>
import &#123;GMapModule&#125; from 'primeng/primeng';
</code>
</pre>

            <h3>Getting Started</h3>
            <p>A map is initialized with options and dimensions. Refer to the google maps api for the list of available options.</p>
<pre>
<code class="language-markup" pCode ngNonBindable>
&lt;p-gmap [options]="options" [style]="&#123;'width':'100%','height':'320px'&#125;" &gt;&lt;/p-gmap&gt;
</code>
</pre>

<pre>
<code class="language-typescript" pCode ngNonBindable>
export class MyModel &#123;

    options: any;
    
    overlays: any[];
    
    ngOnInit() &#123;
        this.options = &#123;
            center: &#123;lat: 36.890257, lng: 30.707417&#125;,
            zoom: 12
        &#125;;
    &#125;

&#125;
</code>
</pre>

            <h3>Overlays</h3>
            <p>GMap can display any type of overlay such as markers, polygons and circles. Overlay instances are bound using the overlays property array. Overlays are aware
            of one-way binding so whenever the array changes, gmap updates itself.</p>
<pre>
<code class="language-markup" pCode ngNonBindable>
&lt;p-gmap [options]="options" [overlays]="overlays" [style]="&#123;'width':'100%','height':'320px'&#125;" &gt;&lt;/p-gmap&gt;
</code>
</pre>

<pre>
<code class="language-typescript" pCode ngNonBindable>
export class MyModel &#123;

    options: any;
    
    overlays: any[];
    
    ngOnInit() &#123;
        this.options = &#123;
            center: &#123;lat: 36.890257, lng: 30.707417&#125;,
            zoom: 12
        &#125;;
        
        this.overlays = [
            new google.maps.Marker(&#123;position: &#123;lat: 36.879466, lng: 30.667648&#125;, title:"Konyaalti"&#125;),
            new google.maps.Marker(&#123;position: &#123;lat: 36.883707, lng: 30.689216&#125;, title:"Ataturk Park"&#125;),
            new google.maps.Marker(&#123;position: &#123;lat: 36.885233, lng: 30.702323&#125;, title:"Oldtown"&#125;),
            new google.maps.Polygon(&#123;paths: [
                &#123;lat: 36.9177, lng: 30.7854&#125;,&#123;lat: 36.8851, lng: 30.7802&#125;,&#123;lat: 36.8829, lng: 30.8111&#125;,&#123;lat: 36.9177, lng: 30.8159&#125;
            ], strokeOpacity: 0.5, strokeWeight: 1,fillColor: '#1976D2', fillOpacity: 0.35
            &#125;),
            new google.maps.Circle(&#123;center: &#123;lat: 36.90707, lng: 30.56533&#125;, fillColor: '#1976D2', fillOpacity: 0.35, strokeWeight: 1, radius: 1500&#125;),
            new google.maps.Polyline(&#123;path: [&#123;lat: 36.86149, lng: 30.63743&#125;,&#123;lat: 36.86341, lng: 30.72463&#125;], geodesic: true, strokeColor: '#FF0000', strokeOpacity: 0.5, strokeWeight: 2&#125;)
        ];
    &#125;
&#125;
</code>
</pre>

            <h3>Events</h3>
            <p>GMap provides common callbacks to hook into events including map click, overlay click and overlay dragging.</p>
<pre>
<code class="language-markup" pCode ngNonBindable>
&lt;p-gmap [options]="options" [overlays]="overlays" [style]="&#123;'width':'100%','height':'320px'&#125;"
            (onMapClick)="handleMapClick($event)" (onOverlayClick)="handleOverlayClick($event)"&gt;&lt;/p-gmap&gt;
</code>
</pre>

<pre>
<code class="language-typescript" pCode ngNonBindable>
export class MyModel &#123;

    options: any;
    
    overlays: any[];
    
    ngOnInit() &#123;
        this.options = &#123;
            center: &#123;lat: 36.890257, lng: 30.707417&#125;,
            zoom: 12
        &#125;;
        
        this.overlays = [
            new google.maps.Marker(&#123;position: &#123;lat: 36.879466, lng: 30.667648&#125;, title:"Konyaalti"&#125;),
            new google.maps.Marker(&#123;position: &#123;lat: 36.883707, lng: 30.689216&#125;, title:"Ataturk Park"&#125;),
            new google.maps.Marker(&#123;position: &#123;lat: 36.885233, lng: 30.702323&#125;, title:"Oldtown"&#125;),
            new google.maps.Polygon(&#123;paths: [
                &#123;lat: 36.9177, lng: 30.7854&#125;,&#123;lat: 36.8851, lng: 30.7802&#125;,&#123;lat: 36.8829, lng: 30.8111&#125;,&#123;lat: 36.9177, lng: 30.8159&#125;
            ], strokeOpacity: 0.5, strokeWeight: 1,fillColor: '#1976D2', fillOpacity: 0.35
            &#125;),
            new google.maps.Circle(&#123;center: &#123;lat: 36.90707, lng: 30.56533&#125;, fillColor: '#1976D2', fillOpacity: 0.35, strokeWeight: 1, radius: 1500&#125;),
            new google.maps.Polyline(&#123;path: [&#123;lat: 36.86149, lng: 30.63743&#125;,&#123;lat: 36.86341, lng: 30.72463&#125;], geodesic: true, strokeColor: '#FF0000', strokeOpacity: 0.5, strokeWeight: 2&#125;)
        ];
    &#125;
    
    handleMapClick(event) &#123;
        //event: MouseEvent of Google Maps api
    &#125;
    
    handleOverlayClick(event) &#123;
        //event.originalEvent: MouseEvent of Google Maps api
        //event.overlay: Clicked overlay     
        //event.map: Map instance   
    &#125;
&#125;
</code>
</pre>

            <h3>Google Maps API</h3>
            <p>In case you need to access the map instance directly, use the getMap() method.</p>
<pre>
<code class="language-markup" pCode ngNonBindable>
&lt;p-gmap #gmap [options]="options"&gt;&lt;/p-gmap&gt;

&lt;button type="button" pButton label="Zoom In" icon="fa-search-plus" (click)="zoomIn(gmap.getMap())"&gt;&lt;/button&gt;
</code>
</pre>

<pre>
<code class="language-typescript" pCode ngNonBindable>
export class MyModel &#123;

    options: any;
    
    overlays: any[];
    
    ngOnInit() &#123;
        this.options = &#123;
            center: &#123;lat: 36.890257, lng: 30.707417&#125;,
            zoom: 12
        &#125;;
    &#125;
    
    zoomIn(map) &#123;
        map.setZoom(map.getZoom()+1);
    &#125;
&#125;
</code>
</pre>
            <p>Another option is to to get the map object directly after init via (onMapReady) event.
               In the example below, google.maps.Map is used for adjusting map bounds to markers.</p>
<pre>
<code class="language-markup" pCode ngNonBindable>
&lt;p-gmap #gmap [options]="options" [overlays]="overlays" [style]="mapStyle"
    (onMapReady)="setMap($event)"&gt;&lt;/p-gmap&gt;
</code>
</pre>
            <p>Then from your component you would write</p>
<pre>
<code class="language-typescript" pCode ngNonBindable>
export class MyModel &#123;

    options: any;
    
    overlays: any[];
    
    map: google.maps.Map;
    
    setMap(event) &#123;
        this.map = event.map;
    &#125;
    
    ngOnInit() &#123;
        let bounds = new google.maps.LatLngBounds();
        this.overlays = [
            new google.maps.Marker(&#123;position: &#123;lat: 36.879466, lng: 30.667648&#125;, title:"Konyaalti"&#125;),
            new google.maps.Marker(&#123;position: &#123;lat: 36.883707, lng: 30.689216&#125;, title:"Ataturk Park"&#125;),
            new google.maps.Marker(&#123;position: &#123;lat: 36.885233, lng: 30.702323&#125;, title:"Oldtown"&#125;),
        ]
        // ... extend bounds
        this.overlays.forEach(marker => &#123;
            bounds.extend(marker.getPosition());
        &#125;);
        
        setTimeout(()=> &#123; // map will need some time to load
            this.map.fitBounds(bounds); // Map object used directly
        &#125;, 1000);
    &#125;
&#125;
</code>
</pre>

            <h3>Properties</h3>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                    <tr>
                        <th>Name</th>
                        <th>Type</th>
                        <th>Default</th>
                        <th>Description</th>
                    </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>options</td>
                            <td>any</td>
                            <td>null</td>
                            <td>Google Maps API configuration object.</td>
                        </tr>
                        <tr>
                            <td>overlays</td>
                            <td>array</td>
                            <td>null</td>
                            <td>An array of overlays to display.</td>
                        </tr>
                        <tr>
                            <td>style</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Inline style of the component.</td>
                        </tr>
                        <tr>
                            <td>styleClass</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Style class of the component.</td>
                        </tr>
                    </tbody>
                </table>
            </div>
            
            <h3>Events</h3>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Parameters</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>onMapClick</td>
                            <td>event: Google Maps MouseEvent</td>
                            <td>Callback to invoke when map is clicked except markers.</td>
                        </tr>
                        <tr>
                            <td>onOverlayClick</td>
                            <td>originalEvent: Google Maps MouseEvent <br>
                                overlay: Clicked overlay <br>
                                map: Map instance <br></td>
                            <td>Callback to invoke when an overlay is clicked.</td>
                        </tr>
                        <tr>
                            <td>onOverlayDragStart</td>
                            <td>originalEvent: Google Maps MouseEvent <br>
                                overlay: Clicked overlay <br>
                                map: Map instance <br></td>
                            <td>Callback to invoke when an overlay drag starts.</td>
                        </tr>
                        <tr>
                            <td>onOverlayDrag</td>
                            <td>originalEvent: Google Maps MouseEvent <br>
                                overlay: Clicked overlay <br>
                                map: Map instance <br></td>
                            <td>Callback to invoke when an overlay is being dragged.</td>
                        </tr>
                        <tr>
                            <td>onOverlayDragEnd</td>
                            <td>originalEvent: Google Maps MouseEvent <br>
                                overlay: Clicked overlay <br>
                                map: Map instance <br></td>
                            <td>Callback to invoke when an overlay drag ends.</td>
                        </tr>
                        <tr>
                            <td>onMapReady</td>
                            <td>event.map: Google Maps Instance</td>
                            <td>Callback to invoke when the map is ready to be used.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h3>Dependencies</h3>
            <p>Google Maps API.</p>
        </p-tabPanel>

        <p-tabPanel header="Source">
            <a href="https://github.com/primefaces/primeng/tree/master/src/app/showcase/components/gmap" class="btn-viewsource" target="_blank">
                <i class="fa fa-github"></i>
                <span>View on GitHub</span>
            </a>
<pre>
<code class="language-markup" pCode ngNonBindable>
&lt;p-growl [value]="msgs"&gt;&lt;/p-growl&gt;

&lt;p-gmap #gmap [style]="&#123;'width':'100%','height':'320px'&#125;" [options]="options" [overlays]="overlays" 
    (onMapClick)="handleMapClick($event)" (onOverlayClick)="handleOverlayClick($event)" (onOverlayDragEnd)="handleDragEnd($event)"&gt;&lt;/p-gmap&gt;
&lt;button type="button" pButton label="Clear" icon="fa-close" (click)="clear()" style="margin-top:10px"&gt;&lt;/button&gt;
&lt;button type="button" pButton label="Zoom In" icon="fa-search-plus" (click)="zoomIn(gmap.getMap())" style="margin-top:10px"&gt;&lt;/button&gt;
&lt;button type="button" pButton label="Zoom Out" icon="fa-search-minus" (click)="zoomOut(gmap.getMap())" style="margin-top:10px"&gt;&lt;/button&gt;

&lt;p-dialog showEffect="fade" [(visible)]="dialogVisible" header="New Location"&gt;
    &lt;div class="ui-g ui-fluid" *ngIf="selectedPosition"&gt;
        &lt;div class="ui-g-2"&gt;&lt;label for="title"&gt;Label&lt;/label&gt;&lt;/div&gt;
        &lt;div class="ui-g-10"&gt;&lt;input type="text" pInputText id="title" [(ngModel)]="markerTitle"&gt;&lt;/div&gt;
        
        &lt;div class="ui-g-2"&gt;&lt;label for="lat"&gt;Lat&lt;/label&gt;&lt;/div&gt;
        &lt;div class="ui-g-10"&gt;&lt;input id="lat" type="text" readonly pInputText [ngModel]="selectedPosition.lat()"&gt;&lt;/div&gt;
        
        &lt;div class="ui-g-2"&gt;&lt;label for="lng"&gt;Lng&lt;/label&gt;&lt;/div&gt;
        &lt;div class="ui-g-10"&gt;&lt;input id="lng" type="text" readonly pInputText [ngModel]="selectedPosition.lng()"&gt;&lt;/div&gt;
        
        &lt;div class="ui-g-2"&gt;&lt;label for="drg"&gt;Drag&lt;/label&gt;&lt;/div&gt;
        &lt;div class="ui-g-10"&gt;&lt;p-checkbox [(ngModel)]="draggable" binary="true" [style]="&#123;'margin-top':'.25em'&#125;"&gt;&lt;/p-checkbox&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;p-footer&gt;
        &lt;div class="ui-dialog-buttonpane ui-helper-clearfix"&gt;
            &lt;button type="button" pButton label="Add Marker" icon="fa-plus" (click)="addMarker()"&gt;&lt;/button&gt;
        &lt;/div&gt;
    &lt;/p-footer&gt;
&lt;/p-dialog&gt;
</code>
</pre>

<pre>
<code class="language-typescript" pCode ngNonBindable>
export class GMapDemo implements OnInit &#123;

    options: any;
    
    overlays: any[];
    
    dialogVisible: boolean;
    
    markerTitle: string;
    
    selectedPosition: any;
    
    infoWindow: any;
    
    draggable: boolean;
    
    msgs: Message[] = [];

    ngOnInit() &#123;
        this.options = &#123;
            center: &#123;lat: 36.890257, lng: 30.707417&#125;,
            zoom: 12
        &#125;;
        
        this.initOverlays();
        
        this.infoWindow = new google.maps.InfoWindow();
    &#125;
    
    handleMapClick(event) &#123;
        this.dialogVisible = true;
        this.selectedPosition = event.latLng;
    &#125;
    
    handleOverlayClick(event) &#123;
        this.msgs = [];
        let isMarker = event.overlay.getTitle != undefined;
        
        if(isMarker) &#123;
            let title = event.overlay.getTitle();
            this.infoWindow.setContent('<div>' + title + '</div>');
            this.infoWindow.open(event.map, event.overlay);
            event.map.setCenter(event.overlay.getPosition());
            
            this.msgs.push(&#123;severity:'info', summary:'Marker Selected', detail: title&#125;);
        &#125;
        else &#123;
            this.msgs.push(&#123;severity:'info', summary:'Shape Selected', detail: ''&#125;);
        &#125;        
    &#125;
    
    addMarker() &#123;
        this.overlays.push(new google.maps.Marker(&#123;position:&#123;lat: this.selectedPosition.lat(), lng: this.selectedPosition.lng()&#125;, title:this.markerTitle, draggable: this.draggable&#125;));
        this.markerTitle = null;
        this.dialogVisible = false;
    &#125;
    
    handleDragEnd(event) &#123;
        this.msgs = [];
        this.msgs.push(&#123;severity:'info', summary:'Marker Dragged', detail: event.overlay.getTitle()&#125;);
    &#125;
    
    initOverlays() &#123;
        if(!this.overlays||!this.overlays.length) &#123;
            this.overlays = [
                new google.maps.Marker(&#123;position: &#123;lat: 36.879466, lng: 30.667648&#125;, title:"Konyaalti"&#125;),
                new google.maps.Marker(&#123;position: &#123;lat: 36.883707, lng: 30.689216&#125;, title:"Ataturk Park"&#125;),
                new google.maps.Marker(&#123;position: &#123;lat: 36.885233, lng: 30.702323&#125;, title:"Oldtown"&#125;),
                new google.maps.Polygon(&#123;paths: [
                    &#123;lat: 36.9177, lng: 30.7854&#125;,&#123;lat: 36.8851, lng: 30.7802&#125;,&#123;lat: 36.8829, lng: 30.8111&#125;,&#123;lat: 36.9177, lng: 30.8159&#125;
                ], strokeOpacity: 0.5, strokeWeight: 1,fillColor: '#1976D2', fillOpacity: 0.35
                &#125;),
                new google.maps.Circle(&#123;center: &#123;lat: 36.90707, lng: 30.56533&#125;, fillColor: '#1976D2', fillOpacity: 0.35, strokeWeight: 1, radius: 1500&#125;),
                new google.maps.Polyline(&#123;path: [&#123;lat: 36.86149, lng: 30.63743&#125;,&#123;lat: 36.86341, lng: 30.72463&#125;], geodesic: true, strokeColor: '#FF0000', strokeOpacity: 0.5, strokeWeight: 2&#125;)
            ];
        &#125;
    &#125;
    
    zoomIn(map) &#123;
        map.setZoom(map.getZoom()+1);
    &#125;
    
    zoomOut(map) &#123;
        map.setZoom(map.getZoom()-1);
    &#125;
    
    clear() &#123;
        this.overlays = [];
    &#125;
&#125;
</code>
</pre>
        </p-tabPanel>
    </p-tabView>
</div>
